﻿
using adb;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Packets;
using PowerStation.Controllers;
using PowerStation.RequestModel.MQTT;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PowerStation.AppCode
{
    /// <summary>
    /// MQTT模块
    /// </summary>
    public class IMqttModel
    {
        private adb.dbBase db = new dbBase();
        private IConfiguration configuart;
        private static MqttFactory mqttFactory = new MqttFactory();
        /// <summary>
        /// 测试
        /// </summary>
        protected static IMqttClient client = null;
        private static Task action = null;
        /// <summary>
        /// 模型
        /// </summary>
        /// <param name="configuart"></param>
        public IMqttModel(IConfiguration configuart)
        {

            this.configuart = configuart;
            var option = new MqttClientOptionsBuilder()
            .WithConnectionUri(this.configuart["mqttUrl"])
            .WithClientId(this.configuart["mqttClientId"])
            .WithCredentials("admin", "admin")
            .Build();
            var factory = new MqttFactory();
            client = factory.CreateMqttClient();
            client.ConnectedAsync += Client_ConnectedAsync;
            client.ConnectAsync(option);

            client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
            // 重连机制
            client.DisconnectedAsync += async e =>
            {
                Console.WriteLine("与服务器之间的连接断开了，正在尝试重新连接");
                // 等待 5s 时间
                await Task.Delay(TimeSpan.FromSeconds(5));
                try
                {
                    // 重新连接
                    await client.ConnectAsync(option);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"重新连接服务器失败:{ex}");
                }
            };

            //if (action == null)
            //{
            //    action = new Task(async () =>
            //    {
            //        while (true)
            //        {
            //            try
            //            {
            //                if (client == null)
            //                {
            //                    var option = new MqttClientOptionsBuilder()
            //                    .WithClientId(this.configuart["mqttClientId"])
            //                    .WithCredentials("admin", "admin")
            //                    .WithConnectionUri(this.configuart["mqttUrl"])
            //                    .Build();
            //                    var factory = new MqttFactory();
            //                    client = factory.CreateMqttClient();
            //                    client.ConnectedAsync += Client_ConnectedAsync;
            //                    var resulte = await client.ConnectAsync(option);
            //                    client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
            //                }
            //                else if (client.IsConnected == false)
            //                {
            //                    var option = new MqttClientOptionsBuilder()
            //                    .WithClientId(this.configuart["mqttClientId"])
            //                    .WithCredentials("admin", "admin")
            //                    .WithConnectionUri(this.configuart["mqttUrl"])
            //                    .Build();
            //                    var resulte = await client.ConnectAsync(option);
            //                }
            //            }
            //            catch (Exception ex) { }
            //            Thread.Sleep(2000);
            //        }
            //    });
            //    action.Start();
            //}
        }

        private async Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
        {
            //开始注册主题
            //using (var conn = this.db.CreateMyDb())
            //{
            //    var topics = await conn.tPowerStationDevice.Where(x => x.dataState == 0 && x.deviceType_keyId_fk != 820002 && x.deviceType_keyId_fk != 820096).ToListAsync();
            //    await client.SubscribeAsync(new MqttClientSubscribeOptions { 
            //        TopicFilters = topics.Select(x=>new MqttTopicFilter() { Topic = x.deviceTopic } ).ToList()
            //    });
            //}
            //return Task.CompletedTask;
        }

        /// <summary>
        /// 收到信息
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
        {
            try
            {
                var json = Encoding.UTF8.GetString(arg.ApplicationMessage.Payload);
                //Dictionary<string, decimal> data = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, decimal>>(json);
                //if (DeviceController.TopicLastValue != null && data != null) {
                //    DeviceController.TopicLastValue[arg.ApplicationMessage.Topic] = data;
                //}
                return Task.CompletedTask;
            }
            catch (Exception ex){
                var json = Encoding.UTF8.GetString(arg.ApplicationMessage.Payload);

                Console.WriteLine("主题>>解析数据出错"+ex.Message+" 数据>>"+ json);
                return Task.CompletedTask;
            }
        }



        /// <summary>
        /// 发送数据到设备
        /// </summary>
        /// <param name="Topic"></param>
        /// <param name="value">发送的值{"value":0},{"value":0.0}</param>
        /// <returns></returns>
        public async Task<bool> SendDataToDevice(string Topic,string value)
        {
            if (client != null && client.IsConnected == true)
            {
                var state = await client.PublishStringAsync(Topic, value);
                return state.ReasonCode == MqttClientPublishReasonCode.Success;
            }

            return false;
        }


        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task<bool> SendNotication(int userId,string msg) {

            if (client == null || client.IsConnected == false)
            {
                var result = await client.PublishAsync(new MQTTnet.MqttApplicationMessage()
                {
                    Topic = "/notication/web/"+msg,
                    Payload = Encoding.UTF8.GetBytes(msg)
                });
                return result.ReasonCode == MqttClientPublishReasonCode.Success;
            }

            return false;
        }

        /// <summary>
        /// 注册主题
        /// </summary>
        /// <param name="topic"></param>
        /// <returns></returns>
        private async Task<bool> SubscribeAsync(string topic) {
           var backValue = await client.SubscribeAsync(new MqttClientSubscribeOptions()
            {
                TopicFilters = new System.Collections.Generic.List<MQTTnet.Packets.MqttTopicFilter>() { new MQTTnet.Packets.MqttTopicFilter() { Topic = topic} },

            });
            return backValue.Items.First().TopicFilter.Topic == topic;
        }


    }
}
